//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>
#include "CKMarshalTst.h"
//#include "_CKMarshalTst.cpp"

#define E_INVALID_ARGUMENT1    0x80070001
#define E_INVALID_ARGUMENT2    0x80070002
#define E_INVALID_ARGUMENT3    0x80070003
#define E_INVALID_ARGUMENT4    0x80070003
#define E_INVALID_ARGUMENT5    0x80070003
#define E_INVALID_VALUE        0x8007000F

PInterface CKMarshalTst::Probe(
    /* [in] */ REIID riid)
{

    if (EIID_IInterface == riid) {
        return (IInterface *)(IKMarshalTst *)this;
    }
    else if (EIID_IKMarshalTst == riid) {
        return (IKMarshalTst *)this;
    }
    else if (EIID_CLASS_INFO == riid) {
        return (PInterface)&ECLSID_CKMarshalTst;
    }
    else if (EIID_INTERFACE_INFO == riid) {
        return (PInterface)&EIID_IKMarshalTst;
    }

    return NULL;
}

UInt32 CKMarshalTst::AddRef(void)
{
    return (UInt32)InterlockedIncrement(&m_Ref);
}

UInt32 CKMarshalTst::Release(void)
{
    int c = InterlockedDecrement(&m_Ref);
    if (c == 0) {
        delete this;
    }
    return c;
}

ECode CKMarshalTst::Aggregate(
    /* [in] */ AggregateType type,
    /* [in] */ PInterface pObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CKMarshalTst::GetDomain(
    /* [out] */ PInterface *pObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CKMarshalTst::KMarshalTst1(
    /* [in] */ Byte CharIn,
    /* [in] */ Byte ByteIn,
    /* [in] */ Boolean BoolIn,
    /* [out] */ Byte * pCharOut,
    /* [out] */ Byte * pByteOut,
    /* [out] */ Boolean * pBoolOut)
{
    *pCharOut = CharIn + 1;
    *pByteOut = ByteIn + 1;
    *pBoolOut = !BoolIn;
    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst2(
    /* [in] */ Int16 ShortIn,
    /* [in] */ Int16 UShortIn,
    /* [out] */ Int16 * pShortOut,
    /* [out] */ Int16 * pUShortOut)
{
    *pShortOut = ShortIn + 1;
    *pUShortOut = UShortIn + 1;
    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst3(
    /* [in] */ Int32 Int32In,
    /* [in] */ Int32 UInt32In,
    /* [out] */ Int32 * pInt32Out,
    /* [out] */ Int32 * pUInt32Out)
{
    *pInt32Out = Int32In + 1;
    *pUInt32Out = UInt32In + 1;
    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst4(
    /* [in] */ Int64 Int64In,
    /* [in] */ Int64 UInt64In,
    /* [out] */ Int64 * pInt64Out,
    /* [out] */ Int64 * pUInt64Out)
{
    *pInt64Out = Int64In + 1;
    *pUInt64Out = UInt64In + 1;
    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst5(
    /* [in] */ Float FloatIn,
    /* [in] */ Double DoubleIn,
    /* [out] */ Float * pFloatOut,
    /* [out] */ Double * pDoubleOut)
{
    *pFloatOut = FloatIn * -1;
    *pDoubleOut = DoubleIn * -1;
    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst6(
    /* [in] */ AChar acIn,
    /* [in] */ WChar wcIn,
    /* [out] */ AChar * pAcOut,
    /* [out] */ WChar * pWcOut)
{
    *pAcOut = acIn + 1;

    if (wcIn != L'W') {
        *pWcOut = L'N';
    }
    else {
        *pWcOut = L'Y';
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst7(
    /* [in] */ const struct TEST_STRUCT1 & StructIn1,
    /* [in] */ const struct TEST_STRUCT1 & StructIn2,
    /* [out] */ PTEST_STRUCT1 pStructOut1,
    /* [out] */ PTEST_STRUCT1 pStructOut2)
{
    TEST_STRUCT1 st1, st2;
    memcpy(&st1, &StructIn1, sizeof(TEST_STRUCT1));
    memcpy(&st2, &StructIn2, sizeof(TEST_STRUCT1));

    st1.cData++;
    st1.sData++;
    st1.iData++;
    st1.ulData++;
    st1.llData++;

    st2.cData++;
    st2.sData++;
    st2.iData++;
    st2.ulData++;
    st2.llData++;

    *pStructOut1 = st1;
    *pStructOut2 = st2;

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst8(
    /* [in] */ const struct TEST_STRUCT2 & StructIn1,
    /* [in] */ const struct TEST_STRUCT2 & StructIn2,
    /* [out] */ PTEST_STRUCT2 pStructOut1,
    /* [out] */ PTEST_STRUCT2 pStructOut2)
{
    TEST_STRUCT2 st1, st2;
    memcpy(&st1, &StructIn1, sizeof(TEST_STRUCT2));
    memcpy(&st2, &StructIn2, sizeof(TEST_STRUCT2));

    st1.iData++;
    st1.SubData.cData++;
    st1.SubData.lData++;

    st2.iData++;
    st2.SubData.cData++;
    st2.SubData.lData++;

    *pStructOut1 = st1;
    *pStructOut2 = st2;

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst9(
    /* [in] */ TestEnum EnumIn,
    /* [out] */ TestEnum * pEnumOut)
{
    if (EnumIn != TestEnum_Data1) {
        kprintf("Serror: EnumIn: %d\n", EnumIn);
        return E_INVALID_ARGUMENT1;
    }

    *pEnumOut = TestEnum_Data2;

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst10(
    /* [in] */ IInterface * pIObjectIn,
    /* [out] */ IInterface ** ppIObjectOut)
{
    if (NULL == pIObjectIn) {
        return E_INVALID_ARGUMENT1;
    }

    IEvent *pEventIn = (IEvent *)pIObjectIn;
    WaitResult wr;
    ECode ec = pEventIn->Wait(&wr, NULL);
    if (FAILED(ec)) {
        kprintf("Serror: Event wait failed ec= 0x%08x\n", ec);
        return E_INVALID_ARGUMENT2;
    }

    IEvent *pEventOut;
    ec = DzCreateEventObj(FALSE, 1, &pEventOut);
    if (FAILED(ec)) {
        kprintf("Serror: CreateEvent failed ec= 0x%08x\n", ec);
        return E_INVALID_ARGUMENT3;
    }

    *ppIObjectOut = pEventOut;

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst11(
    /* [in] */ EMuid * pGuidIn,
    /* [in] */ InterfaceID * pInterfaceIDIn,
    /* [in] */ ClassID * pClassIDIn,
    /* [out] */ EMuid * pGuidOut,
    /* [out] */ InterfaceID * pInterfaceIDOut,
    /* [out] */ ClassID * pClassIDOut)
{
    EMuid guid;
    memcpy(&guid, pGuidIn, sizeof(EMuid));
    guid.Data1++;
    *pGuidOut = guid;

    memcpy(pInterfaceIDOut, pInterfaceIDIn, sizeof(InterfaceID));
    pInterfaceIDOut->Data2++;

    memcpy(&(pClassIDOut->clsid), &(pClassIDIn->clsid), sizeof(EMuid));
    pClassIDOut->clsid.Data3++;
    wchar_t Uunm[256] = {0};
    wcscpy(Uunm, pClassIDIn->pUunm);
    wcscat(Uunm, L".dll");
    pClassIDOut->pUunm = Uunm;

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst12(
    /* [in] */ AString asIn,
    /* [in] */ WString wsIn,
    /* [out] */ AStringBuf * pAsbOut,
    /* [out] */ WStringBuf * pWsbOut)
{
    if (strcmp(asIn, "Hello")) {
        kprintf("Serror: asIn: %s\n", (const char*)asIn);
        return E_INVALID_ARGUMENT1;
    }
    if (wcscmp(wsIn, L"Good")) {
        kprintf("Serror: wsIn: %S\n", (const wchar_t*)wsIn);
        return E_INVALID_ARGUMENT2;
    }

    pAsbOut->Copy(asIn);
    pAsbOut->Append(" world");

    pWsbOut->Copy(wsIn);
    pWsbOut->Append(L" morning");

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst13(
    /* [in] */ const BufferOf<Byte> & AInt8In,
    /* [in] */ const BufferOf<Byte> & AByteIn,
    /* [in] */ const BufferOf<Boolean> & ABoolIn,
    /* [out] */ BufferOf<Byte> * pAInt8Out,
    /* [out] */ BufferOf<Byte> * pAByteOut,
    /* [out] */ BufferOf<Boolean> * pABoolOut)
{
    int i = 0;

    if (pAInt8Out == NULL
        || pAByteOut == NULL
        || pABoolOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AInt8In.GetUsed();
    pAInt8Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt8In[i] == i) {
            (*pAInt8Out)[i] = i + 128;
        }
        else {
            kprintf("AInt8In[%d] = %d", i, AInt8In[i]);
            break;
        }
    }

    used = AByteIn.GetUsed();
    pAByteOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AByteIn[i] == i) {
            (*pAByteOut)[i] = i + 128;
        }
        else {
            kprintf("AByteIn[%d] = %u", i, AByteIn[i]);
            break;
        }
    }

    used = ABoolIn.GetUsed();
    pABoolOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        (*pABoolOut)[i] = !ABoolIn[i];
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst14(
    /* [in] */ const BufferOf<Int16> & AInt16In,
    /* [in] */ const BufferOf<Int16> & AUInt16In,
    /* [out] */ BufferOf<Int16> * pAInt16Out,
    /* [out] */ BufferOf<Int16> * pAUInt16Out)
{
    int i = 0;

    if (pAInt16Out == NULL || pAUInt16Out == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AInt16In.GetUsed();
    pAInt16Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt16In[i] == i) {
            (*pAInt16Out)[i] = i - 255;
        }
        else {
            kprintf("AInt16In[%d] = %d", i, AInt16In[i]);
            break;
        }
    }

    used = AUInt16In.GetUsed();
    pAUInt16Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AUInt16In[i] == i) {
            (*pAUInt16Out)[i] = i + 255;
        }
        else {
            kprintf("pAUInt16In[%d] = %u", i, AUInt16In[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst15(
    /* [in] */ const BufferOf<Int32> & AInt32In,
    /* [in] */ const BufferOf<Int32> & AUInt32In,
    /* [out] */ BufferOf<Int32> * pAInt32Out,
    /* [out] */ BufferOf<Int32> * pAUInt32Out)
{
    int i = 0;

    if (pAInt32Out == NULL || pAUInt32Out == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AInt32In.GetUsed();
    pAInt32Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt32In[i] == i) {
            (*pAInt32Out)[i] = i - 65535;
        }
        else {
            kprintf("AInt32In[%d] = %d", i, AInt32In[i]);
            break;
        }
    }

    used = AUInt32In.GetUsed();
    pAUInt32Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AUInt32In[i] == i) {
            (*pAUInt32Out)[i] = (UInt32)(i + 65535);
        }
        else {
            kprintf("pAUInt32In[%d] = %u", i, AUInt32In[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst16(
    /* [in] */ const BufferOf<Int64> & AInt64In,
    /* [in] */ const BufferOf<Int64> & AUInt64In,
    /* [out] */ BufferOf<Int64> * pAInt64Out,
    /* [out] */ BufferOf<Int64> * pAUInt64Out)
{
    int i = 0;

    if (pAInt64Out == NULL || pAUInt64Out == NULL) {
        return E_INVALID_ARGUMENT;
    }

    int used = AInt64In.GetUsed();
    pAInt64Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt64In[i] == i) {
            (*pAInt64Out)[i] = i - 0xffffffffLL;
        }
        else {
            kprintf("AInt64In[%d] = %I64d", i, AInt64In[i]);
            break;
        }
    }

    used = AUInt64In.GetUsed();
    pAUInt64Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AUInt64In[i] == i) {
            (*pAUInt64Out)[i] = i + 0xffffffffLL;
        }
        else {
            kprintf("pAUInt64In[%d] = %I64u", i, AUInt64In[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst17(
    /* [in] */ const BufferOf<Float> & AFloatIn,
    /* [in] */ const BufferOf<Double> & ADoubleIn,
    /* [out] */ BufferOf<Float> * pAFloatOut,
    /* [out] */ BufferOf<Double> * pADoubleOut)
{
    int i = 0;

    if (pAFloatOut == NULL || pADoubleOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    int used = AFloatIn.GetUsed();
    pAFloatOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AFloatIn[i] == (float)1 * (i + 1)) {
            (*pAFloatOut)[i] = -1 * AFloatIn[i];
        }
        else {
            kprintf("AFloatIn[%d] = %e", i, AFloatIn[i]);
            break;
        }
    }

    used = ADoubleIn.GetUsed();
    pADoubleOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (ADoubleIn[i] == (double)1 * (i + 1)) {
            (*pADoubleOut)[i] = -1 * ADoubleIn[i];
        }
        else {
            kprintf("pADoubleIn[%d] = %e", i, ADoubleIn[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst18(
    /* [in] */ const BufferOf<AChar> & AACharIn,
    /* [in] */ const BufferOf<WChar> & AWCharIn,
    /* [out] */ BufferOf<AChar> * pAACharOut,
    /* [out] */ BufferOf<WChar> * pAWCharOut)
{
    int i = 0;

    if (pAACharOut == NULL || pAWCharOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    int used = AACharIn.GetUsed();
    pAACharOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AACharIn[i] == i % 126) {
            (*pAACharOut)[i] = 1 + AACharIn[i];
        }
        else {
            kprintf("AACharIn[%d] = %c", i, AACharIn[i]);
            break;
        }
    }

    used = AWCharIn.GetUsed();
    pAWCharOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if ((int)AWCharIn[i] == i % 126) {
            (*pAWCharOut)[i] = 1 + AWCharIn[i];
        }
        else {
            kprintf("AWCharIn[%d] = %C", i, AWCharIn[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst19(
    /* [in] */ const BufferOf<struct TEST_STRUCT1> & AStructIn,
    /* [out] */ BufferOf<struct TEST_STRUCT1> * pAStructOut)
{
    int i = 0;

    if (pAStructOut == NULL) return E_INVALID_ARGUMENT;

    int used = AStructIn.GetUsed();
    pAStructOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AStructIn[i].cData == i
            && AStructIn[i].sData == i + 255
            && AStructIn[i].iData == -32768 - i
            && AStructIn[i].ulData == i + 65535
            && AStructIn[i].llData == i + 0xffffffffLL)
        {
            (*pAStructOut)[i].cData = AStructIn[i].cData - 128;
            (*pAStructOut)[i].sData = 1 + AStructIn[i].sData;
            (*pAStructOut)[i].iData = 1 + AStructIn[i].iData;
            (*pAStructOut)[i].ulData = 1 + AStructIn[i].ulData;
            (*pAStructOut)[i].llData = 1 + AStructIn[i].llData;
        }
        else {
            kprintf("AStructIn[%d] = %d, %d, %d, %u, %I64d\n", i,
                    AStructIn[i].cData,
                    AStructIn[i].sData,
                    AStructIn[i].iData,
                    AStructIn[i].ulData,
                    AStructIn[i].llData);
            return E_INVALID_ARGUMENT1;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst20(
    /* [in] */ const BufferOf<struct TEST_STRUCT2> & AStructIn,
    /* [out] */ BufferOf<struct TEST_STRUCT2> * pAStructOut)
{
    int i = 0;

    if (pAStructOut == NULL) return E_INVALID_ARGUMENT;

    int used = AStructIn.GetUsed();
    pAStructOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AStructIn[i].iData == -32768 - i
            && AStructIn[i].SubData.cData == i
            && AStructIn[i].SubData.lData == -32768 - i)
        {
            (*pAStructOut)[i].iData = 1 + AStructIn[i].iData;
            (*pAStructOut)[i].SubData.cData = AStructIn[i].SubData.cData - 128;
            (*pAStructOut)[i].SubData.lData = 1 + AStructIn[i].SubData.lData;
        }
        else {
            kprintf("AStructIn[%d] = %d, %d, %d", i,
                    (*pAStructOut)[i].iData,
                    (*pAStructOut)[i].SubData.cData,
                    (*pAStructOut)[i].SubData.lData);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst21(
    /* [in] */ const BufferOf<IInterface *> & AObjectIn)
{
    int used = AObjectIn.GetUsed();
    if (used != 3) return E_INVALID_ARGUMENT1;

    WaitResult wr;
    EventState stat;
    ECode ec;
    IEvent *pEvent = NULL;
    for (int i = 0; i < 3; i++) {
        pEvent = (IEvent*)AObjectIn[i];
        ec = pEvent->Wait(&wr, &stat);
        if (FAILED(ec)) {
            kprintf("ERR: wait %d failed! %x", i, ec);
            return ec;
        }

        if (stat != i + 100) {
            kprintf("ERR: wait %d stat. %d", i, stat);
            return E_INVALID_VALUE;
        }
    }

    return NOERROR;
}

//ECode CKMarshalTst::KMarshalTst22(
//    /* [out] */ BufferOf<IInterface *> * pAObjectOut)
//{
//    if (pAObjectOut == NULL) return E_INVALID_ARGUMENT;
//
//    int used = pAObjectOut->GetUsed();
//    if (used != 3) return E_INVALID_ARGUMENT1;
//
//    IEvent *pEvent[3] = {0};
//    ECode ec = NULL;
//    int n = 0;
//    for (int i = 0; i < 3; i++) {
//        ec = DzCreateEventObj(TRUE, 0, &pEvent[i]);
//        if (FAILED(ec)) {
//            kprintf("ERR: CreateEvent %d. %x", i, ec);
//            goto ERR;
//        }
//
//        n = i;
//        ec = pEvent[i]->Notify(100 + i);
//        if (FAILED(ec)) {
//            kprintf("ERR: Event %d Notify. %x", i, ec);
//            goto ERR;
//        }
//
//        (*pAObjectOut)[i] = pEvent[i];
//    }
//
//    return NOERROR;
//ERR:
//    for (int j = 0; j <= n; j++) {
//        pEvent[j]->Release();
//    }
//    return ec;
//}

ECode CKMarshalTst::KMarshalTst23(
    /* [in] */ const BufferOf<EGuid> & AEGuidIn,
    /* [in] */ const BufferOf<EMuid> & AEMuidIn,
    /* [out] */ BufferOf<EGuid> * pAEGuidOut,
    /* [out] */ BufferOf<EMuid> * pAEMuidOut)
{
    int i = 0;

    if (pAEGuidOut == NULL || pAEMuidOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AEGuidIn.GetUsed();
    pAEGuidOut->SetUsed(used);
    pAEMuidOut->SetUsed(AEMuidIn.GetUsed());
    for (i = 0; i < used; i++) {
        (*pAEGuidOut)[i].clsid.Data3 = AEGuidIn[i].clsid.Data3 + 1;
        (*pAEMuidOut)[i].Data1 = AEMuidIn[i].Data1 + 1;

        wcscpy((*pAEGuidOut)[i].pUunm, AEGuidIn[i].pUunm);
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst24(
    /* [in] */ const BufferOf<ECode> & AECodeIn,
    /* [out] */ BufferOf<ECode> * pAECodeOut)
{
    int i = 0;

    if (pAECodeOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AECodeIn.GetUsed();
    pAECodeOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AECodeIn[i] == 0) {
            (*pAECodeOut)[i] = i;
        }
        else {
            kprintf("AECodeIn[%d] = %d", i, AECodeIn[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst25(
    /* [in] */ const BufferOf<Byte> & AInt8In,
    /* [in] */ const BufferOf<Int16> & AInt16In,
    /* [in] */ const BufferOf<Int32> & AInt32In,
    /* [in] */ AString AStrIn,
    /* [in] */ WString WStrIn,
    /* [out] */ BufferOf<Byte> * pAInt8Out,
    /* [out] */ BufferOf<Int16> * pAInt16Out,
    /* [out] */ BufferOf<Int32> * pAInt32Out,
    /* [out] */ AStringBuf * pAsbOut,
    /* [out] */ WStringBuf * pWsbOut)
{
    int i = 0, used = 0;

    if (pAInt8Out == NULL
        || pAInt16Out == NULL
        || pAInt32Out == NULL
        || pAsbOut == NULL
        || pWsbOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    used = AInt8In.GetUsed();
    pAInt8Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt8In[i] == i % 128) {
            (*pAInt8Out)[i] = AInt8In[i] + 128;
        }
        else {
            kprintf("AInt8In[%d] = %d", i, AInt8In[i]);
            return E_INVALID_ARGUMENT1;
        }
    }

    used = AInt16In.GetUsed();
    pAInt16Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt16In[i] == i % 32768) {
            (*pAInt16Out)[i] = AInt16In[i] - 32768;
        }
        else {
            kprintf("AInt16In[%d] = %d", i, AInt16In[i]);
            return E_INVALID_ARGUMENT2;
        }
    }

    used = AInt32In.GetUsed();
    pAInt32Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt32In[i] == (Int32)(i % 2147483648UL)) {
            (*pAInt32Out)[i] = AInt32In[i] - 2147483648UL;
        }
        else {
            kprintf("AInt32In[%d] = %d", i, AInt32In[i]);
            return E_INVALID_ARGUMENT3;
        }
    }

    used = AStrIn.GetLength(0x7fffffff);
    for (i = 0; i < used; i++) {
        if (AStrIn[i] == i % 126 + 1) {
            //(*pAsbOut)[i] = AStrIn[i];
        }
        else {
            kprintf("AStrIn[%d] = %c", i, AStrIn[i]);
            return E_INVALID_ARGUMENT4;
        }
    }
    pAsbOut->Copy(AStrIn);

    used = WStrIn.GetLength(0x7fffffff);
    for (i = 0; i < used; i++) {
        if ((int)WStrIn[i] == i % 126 + 1) {
            //(*pWsbOut)[i] = WStrIn[i];
        }
        else {
            kprintf("WStrIn[%d] = %C", i, WStrIn[i]);
            return E_INVALID_ARGUMENT5;
        }
    }
    pWsbOut->Copy(WStrIn);

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst26(
    /* [in] */ const BufferOf<Int64> & AInt64In,
    /* [in] */ const BufferOf<Float> & AFloatIn,
    /* [in] */ const BufferOf<Double> & ADoubleIn,
    /* [in] */ const BufferOf<AChar> & AACharIn,
    /* [in] */ const BufferOf<WChar> & AWCharIn,
    /* [out] */ BufferOf<Int64> * pAInt64Out,
    /* [out] */ BufferOf<Float> * pAFloatOut,
    /* [out] */ BufferOf<Double> * pADoubleOut,
    /* [out] */ BufferOf<AChar> * pAACharOut,
    /* [out] */ BufferOf<WChar> * pAWCharOut)
{
    int i = 0, used = 0;

    if (pAInt64Out == NULL
        || pAFloatOut == NULL
        || pADoubleOut == NULL
        || pAACharOut == NULL
        || pAWCharOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    used = AInt64In.GetUsed();
    pAInt64Out->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AInt64In[i] == i) {
            (*pAInt64Out)[i] = AInt64In[i] - 0xffffffffLL;
        }
        else {
            kprintf("AInt64In[%d] = %I64d", i, AInt64In[i]);
            return E_INVALID_ARGUMENT1;
        }
    }

    used = AFloatIn.GetUsed();
    pAFloatOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AFloatIn[i] == (float)1 * (i + 1)) {
            (*pAFloatOut)[i] = -1 * AFloatIn[i];
        }
        else {
            kprintf("AFloatIn[%d] = %e", i, AFloatIn[i]);
            return E_INVALID_ARGUMENT2;
        }
    }

    used = ADoubleIn.GetUsed();
    pADoubleOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (ADoubleIn[i] == (double)1 * (i + 1)) {
            (*pADoubleOut)[i] = -1 * ADoubleIn[i];
        }
        else {
            kprintf("ADoubleIn[%d] = %e", i, ADoubleIn[i]);
            return E_INVALID_ARGUMENT3;
        }
    }

    used = AACharIn.GetUsed();
    pAACharOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AACharIn[i] == i % 126 + 1) {
            (*pAACharOut)[i] = AACharIn[i];
        }
        else {
            kprintf("AACharIn[%d] = %c", i, AACharIn[i]);
            return E_INVALID_ARGUMENT4;
        }
    }

    used = AWCharIn.GetUsed();
    pAWCharOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if ((int)AWCharIn[i] == i % 126 + 1) {
            (*pAWCharOut)[i] = AWCharIn[i];
        }
        else {
            kprintf("AWCharIn[%d] = %C", i, AWCharIn[i]);
            return E_INVALID_ARGUMENT5;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst33(
    /* [in] */ const ArrayOf<Byte> & AInt8In,
    /* [in] */ const ArrayOf<Byte> & AByteIn,
    /* [in] */ const ArrayOf<Boolean> & ABoolIn,
    /* [out] */ ArrayOf<Byte> * pAInt8Out,
    /* [out] */ ArrayOf<Byte> * pAByteOut,
    /* [out] */ ArrayOf<Boolean> * pABoolOut)
{
    int i = 0;

    if (pAInt8Out == NULL
        || pAByteOut == NULL
        || pABoolOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AInt8In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt8In[i] == i) {
            (*pAInt8Out)[i] = i + 128;
        }
        else {
            kprintf("AInt8In[%d] = %d", i, AInt8In[i]);
            break;
        }
    }

    used = AByteIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AByteIn[i] == i) {
            (*pAByteOut)[i] = i + 128;
        }
        else {
            kprintf("AByteIn[%d] = %u", i, AByteIn[i]);
            break;
        }
    }

    used = ABoolIn.GetLength();
    for (i = 0; i < used; i++) {
        (*pABoolOut)[i] = !ABoolIn[i];
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst34(
    /* [in] */ const ArrayOf<Int16> & AInt16In,
    /* [in] */ const ArrayOf<Int16> & AUInt16In,
    /* [out] */ ArrayOf<Int16> * pAInt16Out,
    /* [out] */ ArrayOf<Int16> * pAUInt16Out)
{
    int i = 0;

    if (pAInt16Out == NULL || pAUInt16Out == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AInt16In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt16In[i] == i) {
            (*pAInt16Out)[i] = i - 255;
        }
        else {
            kprintf("AInt16In[%d] = %d", i, AInt16In[i]);
            break;
        }
    }

    used = AUInt16In.GetLength();
    for (i = 0; i < used; i++) {
        if (AUInt16In[i] == i) {
            (*pAUInt16Out)[i] = i + 255;
        }
        else {
            kprintf("pAUInt16In[%d] = %u", i, AUInt16In[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst35(
    /* [in] */ const ArrayOf<Int32> & AInt32In,
    /* [in] */ const ArrayOf<Int32> & AUInt32In,
    /* [out] */ ArrayOf<Int32> * pAInt32Out,
    /* [out] */ ArrayOf<Int32> * pAUInt32Out)
{
    int i = 0;

    if (pAInt32Out == NULL || pAUInt32Out == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AInt32In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt32In[i] == i) {
            (*pAInt32Out)[i] = i - 65535;
        }
        else {
            kprintf("AInt32In[%d] = %d", i, AInt32In[i]);
            break;
        }
    }

    used = AUInt32In.GetLength();
    for (i = 0; i < used; i++) {
        if (AUInt32In[i] == i) {
            (*pAUInt32Out)[i] = (UInt32)(i + 65535);
        }
        else {
            kprintf("pAUInt32In[%d] = %u", i, AUInt32In[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst36(
    /* [in] */ const ArrayOf<Int64> & AInt64In,
    /* [in] */ const ArrayOf<Int64> & AUInt64In,
    /* [out] */ ArrayOf<Int64> * pAInt64Out,
    /* [out] */ ArrayOf<Int64> * pAUInt64Out)
{
    int i = 0;

    if (pAInt64Out == NULL || pAUInt64Out == NULL) {
        return E_INVALID_ARGUMENT;
    }

    int used = AInt64In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt64In[i] == i) {
            (*pAInt64Out)[i] = i - 0xffffffffLL;
        }
        else {
            kprintf("AInt64In[%d] = %I64d", i, AInt64In[i]);
            break;
        }
    }

    used = AUInt64In.GetLength();
    for (i = 0; i < used; i++) {
        if (AUInt64In[i] == i) {
            (*pAUInt64Out)[i] = i + 0xffffffffLL;
        }
        else {
            kprintf("pAUInt64In[%d] = %I64u", i, AUInt64In[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst37(
    /* [in] */ const ArrayOf<Float> & AFloatIn,
    /* [in] */ const ArrayOf<Double> & ADoubleIn,
    /* [out] */ ArrayOf<Float> * pAFloatOut,
    /* [out] */ ArrayOf<Double> * pADoubleOut)
{
    int i = 0;

    if (pAFloatOut == NULL || pADoubleOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    int used = AFloatIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AFloatIn[i] == (float)1 * (i + 1)) {
            (*pAFloatOut)[i] = -1 * AFloatIn[i];
        }
        else {
            kprintf("AFloatIn[%d] = %e", i, AFloatIn[i]);
            break;
        }
    }

    used = ADoubleIn.GetLength();
    for (i = 0; i < used; i++) {
        if (ADoubleIn[i] == (double)1 * (i + 1)) {
            (*pADoubleOut)[i] = -1 * ADoubleIn[i];
        }
        else {
            kprintf("pADoubleIn[%d] = %e", i, ADoubleIn[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst38(
    /* [in] */ const ArrayOf<AChar> & AACharIn,
    /* [in] */ const ArrayOf<WChar> & AWCharIn,
    /* [out] */ ArrayOf<AChar> * pAACharOut,
    /* [out] */ ArrayOf<WChar> * pAWCharOut)
{
    int i = 0;

    if (pAACharOut == NULL || pAWCharOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    int used = AACharIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AACharIn[i] == i % 126) {
            (*pAACharOut)[i] = 1 + AACharIn[i];
        }
        else {
            kprintf("AACharIn[%d] = %c", i, AACharIn[i]);
            break;
        }
    }

    used = AWCharIn.GetLength();
    for (i = 0; i < used; i++) {
        if ((int)AWCharIn[i] == i % 126) {
            (*pAWCharOut)[i] = 1 + AWCharIn[i];
        }
        else {
            kprintf("AWCharIn[%d] = %C", i, AWCharIn[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst39(
    /* [in] */ const ArrayOf<struct TEST_STRUCT1> & AStructIn,
    /* [out] */ ArrayOf<struct TEST_STRUCT1> * pAStructOut)
{
    int i = 0;

    if (pAStructOut == NULL) return E_INVALID_ARGUMENT;

    int used = AStructIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AStructIn[i].cData == i
            && AStructIn[i].sData == i + 255
            && AStructIn[i].iData == -32768 - i
            && AStructIn[i].ulData == i + 65535
            && AStructIn[i].llData == i + 0xffffffffLL)
        {
            (*pAStructOut)[i].cData = AStructIn[i].cData - 128;
            (*pAStructOut)[i].sData = 1 + AStructIn[i].sData;
            (*pAStructOut)[i].iData = 1 + AStructIn[i].iData;
            (*pAStructOut)[i].ulData = 1 + AStructIn[i].ulData;
            (*pAStructOut)[i].llData = 1 + AStructIn[i].llData;
        }
        else {
            kprintf("AStructIn[%d] = %d, %d, %d, %u, %I64d\n", i,
                    AStructIn[i].cData,
                    AStructIn[i].sData,
                    AStructIn[i].iData,
                    AStructIn[i].ulData,
                    AStructIn[i].llData);
            return E_INVALID_ARGUMENT1;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst40(
    /* [in] */ const ArrayOf<struct TEST_STRUCT2> & AStructIn,
    /* [out] */ ArrayOf<struct TEST_STRUCT2> * pAStructOut)
{
    int i = 0;

    if (pAStructOut == NULL) return E_INVALID_ARGUMENT;

    int used = AStructIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AStructIn[i].iData == -32768 - i
            && AStructIn[i].SubData.cData == i
            && AStructIn[i].SubData.lData == -32768 - i)
        {
            (*pAStructOut)[i].iData = 1 + AStructIn[i].iData;
            (*pAStructOut)[i].SubData.cData = AStructIn[i].SubData.cData - 128;
            (*pAStructOut)[i].SubData.lData = 1 + AStructIn[i].SubData.lData;
        }
        else {
            kprintf("AStructIn[%d] = %d, %d, %d", i,
                    (*pAStructOut)[i].iData,
                    (*pAStructOut)[i].SubData.cData,
                    (*pAStructOut)[i].SubData.lData);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst41(
    /* [in] */ const ArrayOf<IInterface *> & AObjectIn)
{
    int used = AObjectIn.GetLength();
    if (used != 3) return E_INVALID_ARGUMENT1;

    WaitResult wr;
    EventState stat;
    ECode ec;
    IEvent *pEvent = NULL;
    for (int i = 0; i < 3; i++) {
        pEvent = (IEvent*)AObjectIn[i];
        ec = pEvent->Wait(&wr, &stat);
        if (FAILED(ec)) {
            kprintf("ERR: wait %d failed! %x", i, ec);
            return ec;
        }

        if (stat != i + 100) {
            kprintf("ERR: wait %d stat. %d", i, stat);
            return E_INVALID_VALUE;
        }
    }

    return NOERROR;
}

//ECode CKMarshalTst::KMarshalTst42(
//    /* [out] */ ArrayOf<IInterface *> * pAObjectOut)
//{
//    if (pAObjectOut == NULL) return E_INVALID_ARGUMENT;
//
//    int used = pAObjectOut->GetLength();
//    if (used != 3) return E_INVALID_ARGUMENT1;
//
//    IEvent *pEvent[3] = {0};
//    ECode ec = NULL;
//    int n = 0;
//    for (int i = 0; i < 3; i++) {
//        ec = DzCreateEventObj(TRUE, 0, &pEvent[i]);
//        if (FAILED(ec)) {
//            kprintf("ERR: CreateEvent %d. %x", i, ec);
//            goto ERR;
//        }
//
//        n = i;
//        ec = pEvent[i]->Notify(100 + i);
//        if (FAILED(ec)) {
//            kprintf("ERR: Event %d Notify. %x", i, ec);
//            goto ERR;
//        }
//
//        (*pAObjectOut)[i] = pEvent[i];
//    }
//
//    return NOERROR;
//ERR:
//    for (int j = 0; j <= n; j++) {
//        pEvent[j]->Release();
//    }
//    return ec;
//}

ECode CKMarshalTst::KMarshalTst43(
    /* [in] */ const ArrayOf<EGuid> & AEGuidIn,
    /* [in] */ const ArrayOf<EMuid> & AEMuidIn,
    /* [out] */ ArrayOf<EGuid> * pAEGuidOut,
    /* [out] */ ArrayOf<EMuid> * pAEMuidOut)
{
    int i = 0;

    if (pAEGuidOut == NULL || pAEMuidOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AEGuidIn.GetLength();
    for (i = 0; i < used; i++) {
        (*pAEGuidOut)[i].clsid.Data3 = AEGuidIn[i].clsid.Data3 + 1;
        (*pAEMuidOut)[i].Data1 = AEMuidIn[i].Data1 + 1;

        wcscpy((*pAEGuidOut)[i].pUunm, AEGuidIn[i].pUunm);
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst44(
    /* [in] */ const ArrayOf<ECode> & AECodeIn,
    /* [out] */ ArrayOf<ECode> * pAECodeOut)
{
    int i = 0;

    if (pAECodeOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    Int32 used = AECodeIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AECodeIn[i] == 0) {
            (*pAECodeOut)[i] = i;
        }
        else {
            kprintf("AECodeIn[%d] = %d", i, AECodeIn[i]);
            break;
        }
    }

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst45(
    /* [in] */ const ArrayOf<Byte> & AInt8In,
    /* [in] */ const ArrayOf<Int16> & AInt16In,
    /* [in] */ const ArrayOf<Int32> & AInt32In,
    /* [in] */ AString AStrIn,
    /* [in] */ WString WStrIn,
    /* [out] */ ArrayOf<Byte> * pAInt8Out,
    /* [out] */ ArrayOf<Int16> * pAInt16Out,
    /* [out] */ ArrayOf<Int32> * pAInt32Out,
    /* [out] */ AStringBuf * pAsbOut,
    /* [out] */ WStringBuf * pWsbOut)
{
    int i = 0, used = 0;

    if (pAInt8Out == NULL
        || pAInt16Out == NULL
        || pAInt32Out == NULL
        || pAsbOut == NULL
        || pWsbOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    used = AInt8In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt8In[i] == i % 128) {
            (*pAInt8Out)[i] = AInt8In[i] + 128;
        }
        else {
            kprintf("AInt8In[%d] = %d", i, AInt8In[i]);
            return E_INVALID_ARGUMENT1;
        }
    }

    used = AInt16In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt16In[i] == i % 32768) {
            (*pAInt16Out)[i] = AInt16In[i] - 32768;
        }
        else {
            kprintf("AInt16In[%d] = %d", i, AInt16In[i]);
            return E_INVALID_ARGUMENT2;
        }
    }

    used = AInt32In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt32In[i] == (Int32)(i % 2147483648UL)) {
            (*pAInt32Out)[i] = AInt32In[i] - 2147483648UL;
        }
        else {
            kprintf("AInt32In[%d] = %d", i, AInt32In[i]);
            return E_INVALID_ARGUMENT3;
        }
    }

    used = AStrIn.GetLength(0x7fffffff);
    for (i = 0; i < used; i++) {
        if (AStrIn[i] == i % 126 + 1) {
            //(*pAsbOut)[i] = AStrIn[i];
        }
        else {
            kprintf("AStrIn[%d] = %c", i, AStrIn[i]);
            return E_INVALID_ARGUMENT4;
        }
    }
    pAsbOut->Copy(AStrIn);

    used = WStrIn.GetLength(0x7fffffff);
    for (i = 0; i < used; i++) {
        if ((int)WStrIn[i] == i % 126 + 1) {
            //(*pWsbOut)[i] = WStrIn[i];
        }
        else {
            kprintf("WStrIn[%d] = %C", i, WStrIn[i]);
            return E_INVALID_ARGUMENT5;
        }
    }
    pWsbOut->Copy(WStrIn);

    return NOERROR;
}

ECode CKMarshalTst::KMarshalTst46(
    /* [in] */ const ArrayOf<Int64> & AInt64In,
    /* [in] */ const ArrayOf<Float> & AFloatIn,
    /* [in] */ const ArrayOf<Double> & ADoubleIn,
    /* [in] */ const ArrayOf<AChar> & AACharIn,
    /* [in] */ const ArrayOf<WChar> & AWCharIn,
    /* [out] */ ArrayOf<Int64> * pAInt64Out,
    /* [out] */ ArrayOf<Float> * pAFloatOut,
    /* [out] */ ArrayOf<Double> * pADoubleOut,
    /* [out] */ BufferOf<AChar> * pAACharOut,
    /* [out] */ BufferOf<WChar> * pAWCharOut)
{
    int i = 0, used = 0;

    if (pAInt64Out == NULL
        || pAFloatOut == NULL
        || pADoubleOut == NULL
        || pAACharOut == NULL
        || pAWCharOut == NULL) {
        return E_INVALID_ARGUMENT;
    }

    used = AInt64In.GetLength();
    for (i = 0; i < used; i++) {
        if (AInt64In[i] == i) {
            (*pAInt64Out)[i] = AInt64In[i] - 0xffffffffLL;
        }
        else {
            kprintf("AInt64In[%d] = %I64d", i, AInt64In[i]);
            return E_INVALID_ARGUMENT1;
        }
    }

    used = AFloatIn.GetLength();
    for (i = 0; i < used; i++) {
        if (AFloatIn[i] == (float)1 * (i + 1)) {
            (*pAFloatOut)[i] = -1 * AFloatIn[i];
        }
        else {
            kprintf("AFloatIn[%d] = %e", i, AFloatIn[i]);
            return E_INVALID_ARGUMENT2;
        }
    }

    used = ADoubleIn.GetLength();
    for (i = 0; i < used; i++) {
        if (ADoubleIn[i] == (double)1 * (i + 1)) {
            (*pADoubleOut)[i] = -1 * ADoubleIn[i];
        }
        else {
            kprintf("ADoubleIn[%d] = %e", i, ADoubleIn[i]);
            return E_INVALID_ARGUMENT3;
        }
    }

    used = AACharIn.GetLength();
    pAACharOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if (AACharIn[i] == i % 126 + 1) {
            (*pAACharOut)[i] = AACharIn[i];
        }
        else {
            kprintf("AACharIn[%d] = %c", i, AACharIn[i]);
            return E_INVALID_ARGUMENT4;
        }
    }

    used = AWCharIn.GetLength();
    pAWCharOut->SetUsed(used);
    for (i = 0; i < used; i++) {
        if ((int)AWCharIn[i] == i % 126 + 1) {
            (*pAWCharOut)[i] = AWCharIn[i];
        }
        else {
            kprintf("AWCharIn[%d] = %C", i, AWCharIn[i]);
            return E_INVALID_ARGUMENT5;
        }
    }

    return NOERROR;
}
